package dao;


import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import view.MenuPrincipalView;
import model.Pessoa;

class PessoaDAO implements IPessoaDAO {

	@Override
	public boolean insert(Pessoa p) {
		String sql = "insert into pessoa (nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, p.getNome_pessoa() );
			ps.setObject(2, p.getCnpj() );
			ps.setObject(3, p.getIncricao_estadual() );
			ps.setObject(4, p.getInscricao_municipal() );
			ps.setObject(5, p.getCmc() );
			ps.setObject(6, p.getAtividade() );
			ps.setObject(7, p.getRazao_social() );
			ps.setObject(8, p.getCpf() );
			ps.setObject(9, p.getNome_pai() );
			ps.setObject(10, p.getNome_mae() );
			ps.setObject(11, p.getRg() );
			ps.setObject(12, p.getNacionalidade() );
			ps.setObject(13, p.getCtps() );
			ps.setObject(14, p.getSerie_ctps() );
			ps.setObject(15, p.getPis() );
			ps.setObject(16, p.getSalario() );
			ps.setObject(17, p.getSalario_familia() );
			ps.setObject(18, p.getCbo() );
			ps.setObject(19, p.getFuncao() );
			ps.setObject(20, p.getDt_admissao() );
			ps.setObject(21, p.getDt_nascimento() );
			ps.setObject(22, p.getTipo() );
			ps.setObject(23, new Date() );
			ps.setObject(24, new Date() );
			ps.setObject(25, MenuPrincipalView.getUsuarioAtual() );
			ps.setObject(26, p.getPessoa_id_pessoa() );

			return ps.executeUpdate() > 0;
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return false;
	}

	@Override
	public boolean update(Pessoa p) {
		String sql = "update pessoa set nome_pessoa = ?, cnpj = ?, inscricao_estadual = ?, inscricao_municipal = ?, cmc = ?,"
				+ " atividade = ? , razao_social = ?, cpf = ?, nome_pai = ?, nome_mae = ?, rg = ?, nacionalidade = ?,"
				+ " ctps = ?, serie_ctps = ?, pis = ?, salario = ?, salario_familia = ?, cbo = ?, funcao = ?, dt_admissao = ?,"
				+ " dt_nascimento = ?, tipo = ?, dt_alteracao = ?, usuario_alteracao = ?, pessoa_id_pessoa = ?"
				+ " where id_pessoa = ?";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, p.getNome_pessoa() );
			ps.setObject(2, p.getCnpj() );
			ps.setObject(3, p.getIncricao_estadual() );
			ps.setObject(4, p.getInscricao_municipal() );
			ps.setObject(5, p.getCmc() );
			ps.setObject(6, p.getAtividade() );
			ps.setObject(7, p.getRazao_social() );
			ps.setObject(8, p.getCpf() );
			ps.setObject(9, p.getNome_pai() );
			ps.setObject(10, p.getNome_mae() );
			ps.setObject(11, p.getRg() );
			ps.setObject(12, p.getNacionalidade() );
			ps.setObject(13, p.getCtps() );
			ps.setObject(14, p.getSerie_ctps() );
			ps.setObject(15, p.getPis() );
			ps.setObject(16, p.getSalario() );
			ps.setObject(17, p.getSalario_familia() );
			ps.setObject(18, p.getCbo() );
			ps.setObject(19, p.getFuncao() );
			ps.setObject(20, p.getDt_admissao() );
			ps.setObject(21, p.getDt_nascimento() );
			ps.setObject(22, p.getTipo() );
			ps.setObject(23, new Date() );
			ps.setObject(24, MenuPrincipalView.getUsuarioAtual() );
			ps.setObject(25, p.getPessoa_id_pessoa() );
			ps.setObject(26, p.getId_pessoa() );

			return ps.executeUpdate() > 0;
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return false;
	}

	@Override
	public boolean delete(Pessoa p) throws RuntimeException  {
		String sql = "delete from pessoa where id_pessoa = ?";
		Connection conn = ConnectionManneger.getConnection();
		boolean hasErrors = false;
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, p.getId_pessoa() );
			
			return ps.executeUpdate() > 0;
		} catch (SQLException e) {
			hasErrors = true;
			return false;
		} finally {
			ConnectionManneger.closeConnection();
			if (hasErrors) {
				throw new RuntimeException();
			}
		}
	}

	@Override
	public Pessoa findById(int id) {
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where id_pessoa = ?";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, id );
			
			ResultSet rs = ps.executeQuery();
			
			return rs.next() ? 
					new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa")) : null;
					
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return null;
	}

	@Override
	public List<Pessoa> findAll() {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			
			ResultSet rs = ps.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add(					
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
						);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}


	@Override
	public List<Pessoa> findPessoaByName (String searchString) {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where nome_pessoa like ?";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			CallableStatement cs = conn.prepareCall(sql);
			cs.setObject(1, searchString + '%' );
		
			ResultSet rs = cs.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add( 
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
				);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}

	@Override
	public boolean existeRegistro(int id) {
		String sql = "select count(*) as qtd from pessoa where id_pessoa = ?";
		Connection conn = ConnectionManneger.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, id );
			
			ResultSet rs = ps.executeQuery();
			
			rs.next();
			int total = rs.getInt("qtd");
			return total > 0;
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return false;
	}

	@Override
	public boolean insertUpdate(Pessoa p) {
		if(existeRegistro(p.getId_pessoa())){
			return update(p);
		}
		else{
			return insert(p);
		}
	}

	@Override
	public List<Pessoa> findAllPessoaByTipo(String searchString) {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where tipo = ?";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, searchString);
			
			ResultSet rs = ps.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add(					
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
						);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}
	
	public List<Pessoa> findAllFuncionariosByIdEmpresa(int id_empresa) {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where pessoa_id_pessoa = ?";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setObject(1, id_empresa);
			
			ResultSet rs = ps.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add(					
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
						);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}

	@Override
	public int getLastId() {
		String sql = "select max(id_pessoa) as lastId from pessoa";
		Connection conn = ConnectionManneger.getConnection();
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
		
			ResultSet rs = ps.executeQuery();
			
			rs.next();
			int lastId = rs.getInt("lastId");
			return lastId;
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return -1;
	}
	
	@Override
	public List<Pessoa> findPessoaJuridicaByNameCNPJRazao (String searchString) {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where (nome_pessoa like ? or cnpj like ? or razao_social like ?) and tipo = 'JURIDICA' ";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			CallableStatement cs = conn.prepareCall(sql);
			cs.setObject(1, searchString + '%' );
			cs.setObject(2, searchString + '%' );
			cs.setObject(3, searchString + '%' );

			ResultSet rs = cs.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add( 
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
				);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}
	
	@Override
	public List<Pessoa> findPessoaFisicaByNameCpfRg (String searchString) {
		List<Pessoa> pessoas = new ArrayList<Pessoa>();
		String sql = "select id_pessoa, nome_pessoa, cnpj, inscricao_estadual, inscricao_municipal, cmc, atividade, razao_social, cpf,"
				+ " nome_pai, nome_mae, rg, nacionalidade, ctps, serie_ctps, pis, salario, salario_familia, cbo, funcao, dt_admissao,"
				+ " dt_nascimento, tipo, dt_cadastro, dt_alteracao, usuario_alteracao, pessoa_id_pessoa"
				+ " from pessoa where (nome_pessoa like ? or cpf like ? or rg like ?) and tipo = 'FISICA' ";
		Connection conn = ConnectionManneger.getConnection();
		
		try {
			CallableStatement cs = conn.prepareCall(sql);
			cs.setObject(1, searchString + '%' );
			cs.setObject(2, searchString + '%' );
			cs.setObject(3, searchString + '%' );

			ResultSet rs = cs.executeQuery();
			
			while ( rs.next() ) {
				pessoas.add( 
						new Pessoa(rs.getInt("id_pessoa"),
								rs.getString("nome_pessoa"),
								rs.getString("cnpj"),
								rs.getString("inscricao_estadual"),
								rs.getString("inscricao_municipal"),
								rs.getString("cmc"),
								rs.getString("atividade"),
								rs.getString("razao_social"),
								rs.getString("cpf"),
								rs.getString("nome_pai"),
								rs.getString("nome_mae"),
								rs.getString("rg"),
								rs.getString("nacionalidade"),
								rs.getString("ctps"),
								rs.getString("serie_ctps"),
								rs.getString("pis"),
								rs.getDouble("salario"),
								rs.getDouble("salario_familia"),
								rs.getString("cbo"),
								rs.getString("funcao"),
								rs.getDate("dt_admissao"),
								rs.getDate("dt_nascimento"),
								rs.getString("tipo"),
								rs.getDate("dt_cadastro"),
								rs.getDate("dt_alteracao"),
								rs.getString("usuario_alteracao"),
								rs.getInt("pessoa_id_pessoa"))
				);
			} 
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ConnectionManneger.closeConnection();
		}
		return pessoas;
	}

}